Compute Engine VM インスタンスの SSH 接続はどういう仕組みで実現している? #cm_google_cloud_adcal_2024
はじめに
クラスメソッドの Google Cloud Advent Calendar 2024 の 6 日目のブログです!
Google Cloud Advent Calendar 2024 では Google Cloud が大好きな弊社エンジニアが技術ブログを持ち回りで毎日執筆中ですので、ご覧になっていただけると嬉しいです。
本日は少しニッチかもしれませんが、Compute Engine の SSH 接続 について解説します。
API を利用した Compute Engine への SSH 接続
Google Cloud では、Compute Engine Linux VM インスタンスのメンテナンスのため、Cloud Console からの SSH 接続 や gcloud コマンドによる SSH 接続といった API 経由でのアクセスがサポートされています。
Cloud Console からの SSH 接続
あまり気にせずに使うことが多いかもしれませんが、起動直後の VM インスタンスでパスワード認証も公開鍵認証のための設定もしていないのに、どのように SSH のユーザ認証をしているのか気になりませんか?
実は、Cloud Console や gcloud コマンド で SSH 接続すると、公開鍵認証のための準備を Compute Engine が裏側で上手くやってくれているため、ユーザが事前の準備を全く考慮することなく SSH 認証してログインすることができていたのです。
本記事では、Compute Engine が公開鍵認証を準備する裏側のアーキテクチャについて解説していきます。その前にまずは Linux サーバに対する SSH 接続の際の公開鍵認証によるユーザ認証の動作からおさらいしていきましょう。
SSH 公開鍵認証
Linux ベースのサーバに SSH 接続をする際に主に用いられる OSS である OpenSSH の動作を参考に説明していきます。
ユーザによる SSH 接続を開始するとホスト認証とユーザ認証が行われます。ホスト認証とはユーザによるサーバの正当性を検証するための認証です。ユーザ認証とはサーバによるユーザの正当性を検証するための認証です。本記事ではユーザ認証における公開鍵認証の動作を踏まえた Compute Engine のアーキテクチャ解説をしていきますので、ホスト認証についての説明は省略します。
ユーザ認証の主な認証方式としてはパスワード認証と公開鍵認証があります。パスワード認証は、事前にサーバに登録したユーザ/パスワードで認証する方式です。公開鍵認証は、公開鍵と秘密鍵のペアを用いた認証です。
公開鍵認証では、ユーザが公開鍵と秘密鍵のペアを生成し、公開鍵をサーバにアップロードする準備が必要です。これらの鍵ペアを用いた SSH 認証の仕組みは簡単に絵にすると以下のイメージです。
SSH 公開鍵認証のイメージ
Compute Engine デフォルトの SSH 認証の仕組み
公開鍵認証は、事前にユーザによる鍵ペアの生成とサーバへの公開鍵アップロードが必要であることが理解できたと思います。しかし、Compute Engine Linux VM インスタンスに対して Cloud Console や gcloud コマンドを利用して SSH 接続する場合、このようなプロセスをユーザ側で実施することなく公開鍵認証による SSH 認証が可能となります。
Compute Engine で VM インスタンスを作成する際にデフォルトの設定にすると、メタデータマネージド SSH 接続という方式で SSH 接続することとなります。この記事ではメタデータマネージド SSH 接続の詳細アーキテクチャをこのあと説明していきます。もう一つ OS Login マネージド SSH 接続 という方法もありますが、こちらは別の機会で詳細説明したいと思います。
メタデータマネージド SSH 接続は、Cloud Console や gcloud コマンドによって SSH 接続がリクエストされた際に、Compute Engine のメタデータ を利用して公開鍵認証の仕組みを構成する方法です。
Compute Engine のメタデータとは VM インスタンスを構成するための情報を Key-Value ペアの形式で保持されたデータであり、VM インスタンスの起動時などに読み込むことで、起動スクリプトを指定したり、インスタンスの設定を指定したりできます。
Compute Engine のメタデータを利用した公開鍵認証の準備の仕組みをイメージにしてみました。以下は Cloud Shell から gcloud コマンドで VM インスタンスに ssh 接続する例です。
メタデータマネージド SSH 接続による公開鍵認証
実際に動作を確認しながら見ていきます。
① SSH 接続をリクエスト
事前に検証のために Compute Engine の VM インスタンスを作成しました。ssh-vm
というインスタンス名で、ゾーンはasia-northeast1-a
、イメージは Debian GNU/Linux 12 (bookworm)
としました。
ちなみに、VM インスタンス作成画面の [詳細オプション] を開き、[セキュリティ] -> [VM アクセス] を見ると、SSH 接続する際に SSH 認証鍵が自動生成されるとの説明が確認できます。これがメタデータマネージド SSH 接続による SSH 認証を意味しています。
Cloud Shell から以下コマンドを実行して作成した VM インスタンスに SSH 接続します。
$ gcloud compute ssh --zone=asia-northeast1-a ssh-vm
② 公開鍵と秘密鍵の鍵ペアを生成
Compute Engine は公開鍵と秘密鍵の鍵ペアを生成します。
③ 秘密鍵と公開鍵をローカル環境に保存
Compute Engine は秘密鍵を SSH 接続元のローカル環境に保存します。Cloud Shell から ~/.ssh/
を見てみると google_compute_engine
(秘密鍵) と google_compute_engine.pub
(公開鍵) が保存されていることがわかります。
$ ls -la ~/.ssh/
total 20
drwx------ 2 murata_kazuhiro murata_kazuhiro 4096 Dec 6 08:19 .
drwxr-xr-x 37 murata_kazuhiro murata_kazuhiro 4096 Dec 6 08:13 ..
-rw------- 1 murata_kazuhiro murata_kazuhiro 2635 Dec 6 08:13 google_compute_engine
-rw-r--r-- 1 murata_kazuhiro murata_kazuhiro 593 Dec 6 08:13 google_compute_engine.pub
-rw------- 1 murata_kazuhiro murata_kazuhiro 1664 Dec 6 08:19 google_compute_known_hosts
④ SSH ユーザ名と公開鍵をメタデータとして保存
Compute Engine は SSH ユーザ名と公開鍵をメタデータとしてメタデータサーバに保存します。
Cloud Console より [Compute Engine] -> [メタデータ] を選択し、[SSH 認証鍵] のタブをクリックすると、以下のようにユーザmurata_kazuhiro
に対する公開鍵がアップロードされているのがわかります。
上記の公開鍵の内容がローカル環境(Cloud Shell)に保存されている内容と一致することも確認できます。
⑤ ユーザアカウントを作成
VM インスタンスはメタデータに保存されたユーザ名を参照し、アカウントを作成します。
SSH ログイン後のプロンプトを見るとmurata_kazuhiro
というユーザでログインしていることがわかります。メタデータとして保存されているユーザ名と一致することが確認できます。
murata_kazuhiro@ssh-vm:~$ cat /etc/passwd | grep "^murata"
murata_kazuhiro:x:1000:1001::/home/murata_kazuhiro:/bin/bash
⑥ ユーザ環境に公開鍵をダウンロード
VM インスタンスはメタデータに保存された公開鍵をダウンロードし、作成したユーザの ~/.ssh/authorized_keys
ファイルに格納します。
murata_kazuhiro@ssh-vm:~$ ls ~/.ssh/authorized_keys
/home/murata_kazuhiro/.ssh/authorized_keys
中身を確認すると、メタデータとして保存されている公開鍵の内容と一致することが確認できます。
ここまでが Compute Engine によるメタデータマネージド SSH 接続の公開鍵認証のプロセスです。VM インスタンスのユーザ環境に公開鍵がアップロードされたことで公開鍵認証による SSH 認証が実現できることとなります。
ここまでで説明したアーキテクチャの詳細については以下公式ドキュメントを参考に整理いたしました。
おわりに
Compute Engine Linux VM インスタンスの SSH 接続の仕組みについて説明いたしました。
本記事は Cloud Console や gcloud コマンドを利用した API 経由の SSH 接続の動作についての解説ですので、VM インスタンスの外部 IP アドレスから SSH 接続するケースにおいては、VM インスタンス上にユーザ認証のための準備(ユーザ設定や公開鍵配置)をしておく必要があるためご注意ください。
また、もう一つの SSH 接続方式である OS Login マネージド SSH 接続についてもどこかで記事にしたいと思います。
Google Cloud Advent Calendar 2024 の 明日 12/7 投稿は みかみ です!